local CURRENT_UNIT, CURRENT_ANCHOR, CURRENT_MODULE, CURRENT_TIMER = "player", "", "", "";
local ANCHOR_FRAMES = {};

local excludedSettings = {"enabled", "blizzBuffs", "isAnnouncing", "noDuration"};

local set = function(...)
    if CURRENT_UNIT == "player" or excludedSettings[...] then
        PlayerAuras:Set(...);
    else
        -- terrible for memory, but it's a GUI, so I don't care
        local t = {...};
        t[1] = t[1] .. (CURRENT_UNIT == "player" and "" or "-" .. CURRENT_UNIT);
        PlayerAuras:Set(unpack(t));
    end
end

local get = function(...)
    if CURRENT_UNIT == "player" or excludedSettings[...] then
        return PlayerAuras:Get(...);
    else
        -- terrible for memory, but it's a GUI, so I don't care
        local t = {...};
        t[1] = t[1] .. (CURRENT_UNIT == "player" and "" or "-" .. CURRENT_UNIT);
        return PlayerAuras:Get(unpack(t));
    end
end

local optionsTable = {
    { -- section 1
        { -- column 1
            {
                title = "Enabled",
                type = "checkButton",
                tooltipText = "Enables or disables the addon.",
                setting = "enabled",
            },
            {
                title = "Blizzard Buffs",
                type = "checkButton",
                tooltipText = "If checked, Blizzard's default buffs will be shown.",
                setting = "blizzBuffs",
            },
        },
        { -- column 2
            {
                title = "Announce",
                type = "checkButton",
                tooltipText = "If unchecked, attempting to announce a timer will result in no action.",
                setting = "isAnnouncing",
            },
            {
                title = "Key Bindings",
                type = "dropDown",
                tooltipText = "Allows you to change the key bindings for various timer-related functions.",
                func = function() PlayerAuras:KBDropDown() end,
            },
        },
        { -- column 3
            {
                title = "No Duration",
                type = "editBoxDropDown",
                tooltipText = "Add here the names of timers you want to be displayed as having no duration.  The timer name much match exactly (case insensitive).",
                setting = "noDuration",
            },
        },
    },
    { -- section 2
        { -- column 1
            { -- row 1
                {
                    type = "text",
                    text = "Select Unit to Customize: ",
                },
                {
                    title = "player",
                    type = "dropDown",
                    tooltipText = "Select which unit you want to customize.  All below settings are affected by this selection.",
                    func = function(self)
                        local info;
                        for name in AsheylaLib:Alphabetize(PlayerAuras.units) do
                            info = UIDropDownMenu_CreateInfo();
                            info.text = name;
                            info.checked = name == CURRENT_UNIT;
                            info.func = function() 
                                CURRENT_UNIT = name;
                                getglobal(self:GetParent():GetName() .. "Text"):SetText(name);
                                GUILib:RefreshCurrentPanel();
                                CloseDropDownMenus(); 
                            end
                            UIDropDownMenu_AddButton(info);
                        end
                    end,
                },
                {
                    title = "Enabled",
                    type = "checkButton",
                    tooltipText = "If checked, timers for this unit will be created.",
                    setting = "showUnit",
                },
            },
        },
    },
    { -- section 2
        { -- column 1
            {
                type = "text",
                text = "Buffs",
            },
            {
                title = "Blocked Timers",
                type = "editBoxDropDown",
                tooltipText = "Add here the names of timers you do not wish to see onscreen.  The timer name much match exactly (case insensitive) to be blocked.",
                setting = "blocked-Buffs",
            },
            {
                title = "Standard Announce",
                type = "editBoxString",
                tooltipText = [[Sets the message that will be sent when you announce a timer.  You can use the following replacements:

    %s: Name of the timer
    %d: Time remaining]]
                ,
                setting = "standardAnnounce-Buffs",
            },
            {
                title = "No Dur. Announce",
                type = "editBoxString",
                tooltipText = [[Sets the message that will be sent when you announce a timer with no duration.  You can use the following replacements:

    %s: Name of the timer]]
                ,
                setting = "noDurationAnnounce-Buffs",
            },
            {
                title = "Display Name",
                type = "editBoxString",
                tooltipText = "Sets the text to be displayed as the name of the Buffs group.  If you set this to a value another group is also using (in the same anchor), the two groups will merge into one.",
                setting = "buffsName",
            },
            {
                title = "Standard Setting",
                type = "dropDown",
                tooltipText = "Select the timer setting you want to apply to standard timers.",
                func = function()
                    local setting = "standardSetting-Buffs";
                    local info;
                    for name, settings in AsheylaLib:Alphabetize(TimerLib:Get("timerSettings")) do
                        info = UIDropDownMenu_CreateInfo();
                        info.text = name;
                        info.checked = name == PlayerAuras:Get(setting);
                        info.func = function() 
                            PlayerAuras:Set(setting, name);
                            CloseDropDownMenus(); 
                        end
                        UIDropDownMenu_AddButton(info);
                    end
                    
                    info = UIDropDownMenu_CreateInfo();
                    info.text = "None";
                    info.tooltipTitle = "Description";
                    info.tooltipText = "If you select 'None', the default for the anchor will be used instead.";
                    info.checked = PlayerAuras:Get(setting) == nil;
                    info.func = function() 
                        PlayerAuras:Set(setting, nil);
                        CloseDropDownMenus(); 
                    end
                    UIDropDownMenu_AddButton(info);
                end,
            },
            {
                title = "No Dur. Setting",
                type = "dropDown",
                tooltipText = "Select the timer setting you want to apply to timers with no duration.",
                func = function()
                    local setting = "noDurSetting-Buffs";
                    local info;
                    for name, settings in AsheylaLib:Alphabetize(TimerLib:Get("timerSettings")) do
                        info = UIDropDownMenu_CreateInfo();
                        info.text = name;
                        info.checked = name == PlayerAuras:Get(setting);
                        info.func = function() 
                            PlayerAuras:Set(setting, name);
                            CloseDropDownMenus(); 
                        end
                        UIDropDownMenu_AddButton(info);
                    end
                    
                    info = UIDropDownMenu_CreateInfo();
                    info.text = "None";
                    info.tooltipTitle = "Description";
                    info.tooltipText = "If you select 'None', the default for the anchor will be used instead.";
                    info.checked = PlayerAuras:Get(setting) == nil;
                    info.func = function() 
                        PlayerAuras:Set(setting, nil);
                        CloseDropDownMenus(); 
                    end
                    UIDropDownMenu_AddButton(info);
                end,
            },
            "BREAK",
        },
        { -- column 2
            {
                type = "text",
                text = "Debuffs",
            },
            {
                title = "Blocked Timers",
                type = "editBoxDropDown",
                tooltipText = "Add here the names of timers you do not wish to see onscreen.  The timer name much match exactly (case insensitive) to be blocked.",
                setting = "blocked-Debuffs",
            },
            {
                title = "Standard Announce",
                type = "editBoxString",
                tooltipText = [[Sets the message that will be sent when you announce a timer.  You can use the following replacements:

    %s: Name of the timer
    %d: Time remaining]]
                ,
                setting = "standardAnnounce-Debuffs",
            },
            {
                title = "No Dur. Announce",
                type = "editBoxString",
                tooltipText = [[Sets the message that will be sent when you announce a timer with no duration.  You can use the following replacements:

    %s: Name of the timer]]
                ,
                setting = "noDurationAnnounce-Debuffs",
            },
            {
                title = "Display Name",
                type = "editBoxString",
                tooltipText = "Sets the text to be displayed as the name of the Debuffs group.  If you set this to a value another group is also using (in the same anchor), the two groups will merge into one.",
                setting = "debuffsName",
            },
            "BREAK",
        },
        { -- column 3
            {
                type = "text",
                text = "Debuffs, Cont'd",
            },
            {
                title = "Standard Setting",
                type = "dropDown",
                tooltipText = "Select the timer setting you want to apply to standard timers.",
                func = function()
                    local setting = "standardSetting-Debuffs";
                    local info;
                    for name, settings in AsheylaLib:Alphabetize(TimerLib:Get("timerSettings")) do
                        info = UIDropDownMenu_CreateInfo();
                        info.text = name;
                        info.checked = name == PlayerAuras:Get(setting);
                        info.func = function() 
                            PlayerAuras:Set(setting, name);
                            CloseDropDownMenus(); 
                        end
                        UIDropDownMenu_AddButton(info);
                    end
                    
                    info = UIDropDownMenu_CreateInfo();
                    info.text = "None";
                    info.tooltipTitle = "Description";
                    info.tooltipText = "If you select 'None', the default for the anchor will be used instead.";
                    info.checked = PlayerAuras:Get(setting) == nil;
                    info.func = function() 
                        PlayerAuras:Set(setting, nil);
                        CloseDropDownMenus(); 
                    end
                    UIDropDownMenu_AddButton(info);
                end,
            },
            {
                title = "No Dur. Setting",
                type = "dropDown",
                tooltipText = "Select the timer setting you want to apply to timers with no duration.",
                func = function()
                    local setting = "noDurSetting-Debuffs";
                    local info;
                    for name, settings in AsheylaLib:Alphabetize(TimerLib:Get("timerSettings")) do
                        info = UIDropDownMenu_CreateInfo();
                        info.text = name;
                        info.checked = name == PlayerAuras:Get(setting);
                        info.func = function() 
                            PlayerAuras:Set(setting, name);
                            CloseDropDownMenus(); 
                        end
                        UIDropDownMenu_AddButton(info);
                    end
                    
                    info = UIDropDownMenu_CreateInfo();
                    info.text = "None";
                    info.tooltipTitle = "Description";
                    info.tooltipText = "If you select 'None', the default for the anchor will be used instead.";
                    info.checked = PlayerAuras:Get(setting) == nil;
                    info.func = function() 
                        PlayerAuras:Set(setting, nil);
                        CloseDropDownMenus(); 
                    end
                    UIDropDownMenu_AddButton(info);
                end,
            },
            {
                title = "Debuff Type Setting",
                type = "dropDown",
                tooltipText = "Select the timer setting you want to apply to all debuffs of a certain type.",
                func = function()
                    if UIDROPDOWNMENU_MENU_LEVEL == 1 then
                        for _, type in ipairs({"Magic", "Curse", "Disease", "Poison", "Physical"}) do
                            info = UIDropDownMenu_CreateInfo();
                            info.text = type;
                            info.value = type;
                            info.hasArrow = 1;
                            UIDropDownMenu_AddButton(info);
                        end
                    elseif UIDROPDOWNMENU_MENU_LEVEL == 2 then
                        local setting = "timerSetting-" .. UIDROPDOWNMENU_MENU_VALUE;
                        local info;
                        for name, settings in AsheylaLib:Alphabetize(TimerLib:Get("timerSettings")) do
                            info = UIDropDownMenu_CreateInfo();
                            info.text = name;
                            info.checked = name == PlayerAuras:Get(setting);
                            info.func = function() 
                                PlayerAuras:Set(setting, name);
                                CloseDropDownMenus(); 
                            end
                            UIDropDownMenu_AddButton(info, UIDROPDOWNMENU_MENU_LEVEL);
                        end
                        
                        info = UIDropDownMenu_CreateInfo();
                        info.text = "None";
                        info.tooltipTitle = "Description";
                        info.tooltipText = "If you select 'None', the standard/no duration settings will be used instead.";
                        info.checked = PlayerAuras:Get(setting) == nil;
                        info.func = function() 
                            PlayerAuras:Set(setting, nil);
                            CloseDropDownMenus(); 
                        end
                        UIDropDownMenu_AddButton(info, UIDROPDOWNMENU_MENU_LEVEL);
                    end
                end,
            },
            "BREAK",
        },
    },
    { -- section 3
        { -- column 1
            { -- row 1
                {
                    type = "text",
                    text = "Select Anchor to Customize: ",
                },
                {
                    title = "(Select from DropDown Menu)",
                    type = "dropDown",
                    tooltipText = "Select the anchor you want to customize.",
                    func = function(self)
                        local info;
                        for name, settings in AsheylaLib:Alphabetize(TimerLib:Get("anchorSettings")) do
                            if name ~= "Default Anchor" and name ~= "DoTimer Mouseover" and name ~= "Notifications Anchor" then
                                info = UIDropDownMenu_CreateInfo();
                                info.text = name;
                                info.checked = name == CURRENT_ANCHOR;
                                info.func = function() 
                                    CURRENT_ANCHOR = name;
                                    getglobal(self:GetParent():GetName() .. "Text"):SetText(name);
                                    for frame in pairs(ANCHOR_FRAMES) do
                                        frame:Update();
                                    end
                                    CloseDropDownMenus(); 
                                end
                                UIDropDownMenu_AddButton(info);
                            end
                        end
                    end,
                    scripts = {
                        OnShow = function(self)
                            for name, settings in pairs(PlayerAuras:Get("userAnchors-Buffs" .. (CURRENT_UNIT == "player" and "" or "-" .. CURRENT_UNIT))) do
                                if settings.default then
                                    CURRENT_ANCHOR = name;
                                    getglobal(self:GetName() .. "Text"):SetText(name);
                                    for frame in pairs(ANCHOR_FRAMES) do
                                        frame:Update();
                                    end
                                end
                            end
                        end,
                    },
                },
            },
            { -- row 2
                {
                    type = "text",
                    text = "Select Module to Customize: ",
                },
                {
                    title = "(Select from DropDown Menu)",
                    type = "dropDown",
                    tooltipText = "Select the module you want to customize.",
                    func = function(self)
                        local info;
                        info = UIDropDownMenu_CreateInfo();
                        info.text = "Buffs";
                        info.checked = "Buffs" .. (CURRENT_UNIT == "player" and "" or "-" .. CURRENT_UNIT) == CURRENT_MODULE;
                        info.func = function() 
                            CURRENT_MODULE = "Buffs" .. (CURRENT_UNIT == "player" and "" or "-" .. CURRENT_UNIT);
                            getglobal(self:GetParent():GetName() .. "Text"):SetText("Buffs");
                            for frame in pairs(ANCHOR_FRAMES) do
                                frame:Update();
                            end
                            CloseDropDownMenus(); 
                        end
                        UIDropDownMenu_AddButton(info);
                        
                        info = UIDropDownMenu_CreateInfo();
                        info.text = "Debuffs";
                        info.checked = "Debuffs" .. (CURRENT_UNIT == "player" and "" or "-" .. CURRENT_UNIT) == CURRENT_MODULE;
                        info.func = function() 
                            CURRENT_MODULE = "Debuffs" .. (CURRENT_UNIT == "player" and "" or "-" .. CURRENT_UNIT);
                            getglobal(self:GetParent():GetName() .. "Text"):SetText("Debuffs");
                            for frame in pairs(ANCHOR_FRAMES) do
                                frame:Update();
                            end
                            CloseDropDownMenus(); 
                        end
                        UIDropDownMenu_AddButton(info);
                    end,
                    scripts = {
                        OnShow = function(self)
                            CURRENT_MODULE = "Buffs" .. (CURRENT_UNIT == "player" and "" or "-" .. CURRENT_UNIT);
                            getglobal(self:GetName() .. "Text"):SetText("Buffs");
                            for frame in pairs(ANCHOR_FRAMES) do
                                frame:Update();
                            end
                        end,
                    },
                },
            },
        },
    },
    { -- section 4
        { -- column 1
            {
                title = "Make this the default anchor",
                type = "checkButton",
                tooltipText = "If checked, the module will be moved to this anchor.",
                scripts = {
                    OnShow = function(self)
                        if not self.loaded then
                            self.loaded = true;
                            self.Update = function(self)
                                self:SetChecked(PlayerAuras:Get("userAnchors-" .. CURRENT_MODULE, CURRENT_ANCHOR, "default"));
                            end
                            ANCHOR_FRAMES[self] = true;
                        end
                        self:Update();
                    end,
                    OnClick = function(self)
                        if self:GetChecked() then
                            print(CURRENT_MODULE);
                            for name, settings in pairs(PlayerAuras:Get("userAnchors-" .. CURRENT_MODULE)) do
                                if name ~= CURRENT_ANCHOR then settings.default = nil; end
                            end
                            PlayerAuras:Set("userAnchors-" .. CURRENT_MODULE, CURRENT_ANCHOR, "default", 1);
                        else
                            self:SetChecked(true);
                            AsheylaLib:AlertUser("You cannot uncheck this setting.  You must check it in another anchor to change it.");
                        end
                    end,
                },
            },
            {
                title = "Move No Duration timers here",
                type = "checkButton",
                tooltipText = "If checked, timers with no duration will be moved to this anchor.",
                scripts = {
                    OnShow = function(self)
                        if not self.loaded then
                            self.loaded = true;
                            self.Update = function(self)
                                self:SetChecked(PlayerAuras:Get("userAnchors-" .. CURRENT_MODULE, CURRENT_ANCHOR, "noDurLoc"));
                            end
                            ANCHOR_FRAMES[self] = true;
                        end
                        self:Update();
                    end,
                    OnClick = function(self)
                        if self:GetChecked() then
                            for name, settings in pairs(PlayerAuras:Get("userAnchors-" .. CURRENT_MODULE)) do
                                if name ~= CURRENT_ANCHOR then settings.noDurLoc = nil; end
                            end
                            PlayerAuras:Set("userAnchors-" .. CURRENT_MODULE, CURRENT_ANCHOR, "noDurLoc", 1);
                        else
                            PlayerAuras:Set("userAnchors-" .. CURRENT_MODULE, CURRENT_ANCHOR, "noDurLoc", nil);
                        end
                    end,
                },
            },
            { -- row
                {
                    type = "text",
                    small = true,
                    text = "Move these timers:",
                },
                {
                    title = "<Timer Name>",
                    type = "editBoxDropDown",
                    tooltipText = "Type in here the names of timers you want moved to this anchor.  The timer name must match only a fragment (case insensitive) to apply.",
                    scripts = {
                        OnEnterPressed = function(self) 
                            local text = self:GetText();
                            PlayerAuras:Set("userAnchors-" .. CURRENT_MODULE, CURRENT_ANCHOR, "timers", string.lower(text), 1);
                            self:ClearFocus();
                        end,
                    },
                    func = function()
                        local timers = PlayerAuras:Get("userAnchors-" .. CURRENT_MODULE, CURRENT_ANCHOR, "timers");
                        if timers then
                            local info;
                            for name in pairs(timers) do
                                info = UIDropDownMenu_CreateInfo();
                                info.text = name;
                                info.notCheckable = 1;
                                info.func = function() 
                                    PlayerAuras:Set("userAnchors-" .. CURRENT_MODULE, CURRENT_ANCHOR, "timers", name, nil);
                                    CloseDropDownMenus(); 
                                end
                                UIDropDownMenu_AddButton(info);
                            end
                        end
                    end,
                },
                {
                    type = "text",
                    small = true,
                    text = "here.",
                },
            },
            { -- row
                {
                    type = "text",
                    small = true,
                    text = "Apply this timer setting:",
                },
                {
                    title = "",
                    type = "dropDown",
                    tooltipText = "Select the timer setting you want to apply to specific timers.",
                    func = function()
                        local info;
                        for name, settings in AsheylaLib:Alphabetize(TimerLib:Get("timerSettings")) do
                            info = UIDropDownMenu_CreateInfo();
                            info.text = name;
                            info.checked = name == CURRENT_TIMER;
                            info.func = function() 
                                CURRENT_TIMER = name;
                                CloseDropDownMenus(); 
                            end
                            UIDropDownMenu_AddButton(info);
                        end
                    end,
                    scripts = {
                        OnShow = function(self)
                            CURRENT_TIMER = "Default Timer";
                        end,
                    },
                },
                {
                    type = "text",
                    small = true,
                    text = "to these timers:",
                },
                {
                    title = "<Timer Name>",
                    type = "editBoxDropDown",
                    tooltipText = "Type in here the names of timers you want to apply to the timer setting.  The timer name must match only a fragment (case insensitive) to apply.",
                    scripts = {
                        OnEnterPressed = function(self) 
                            local text = self:GetText();
                            PlayerAuras:Set("userAnchors-" .. CURRENT_MODULE, CURRENT_ANCHOR, "timerSettings", CURRENT_TIMER, string.lower(text), 1);
                            self:ClearFocus();
                        end,
                    },
                    func = function()
                        local timers = PlayerAuras:Get("userAnchors-" .. CURRENT_MODULE, CURRENT_ANCHOR, "timerSettings", CURRENT_TIMER);
                        if timers then
                            local info;
                            for name in pairs(timers) do
                                info = UIDropDownMenu_CreateInfo();
                                info.text = name;
                                info.notCheckable = 1;
                                info.func = function() 
                                    PlayerAuras:Set("userAnchors-" .. CURRENT_MODULE, CURRENT_ANCHOR, "timerSettings", CURRENT_TIMER, name, nil);
                                    CloseDropDownMenus(); 
                                end
                                UIDropDownMenu_AddButton(info);
                            end
                        end
                    end,
                },
            },
        },
    },
};

local function createPAGUI()
    if not AsheylaLib:InSimpleMode() then
        GUILib:SetGUIPanel("DoTimer", "PlayerAuras", PlayerAuras, optionsTable, {set = set, get = get});
    end
end
createPAGUI();
GUILib:AddGUICreationScript(createPAGUI);
